#include "./server/UdpServer.h"
#include "../../src/time/Time.h"
#include "../../src/log/LogFactory.h"

namespace udp_recv_msg
{
	class MyUdpService : public UdpServer
	{
	public:
		MyUdpService(LibTools::SOCKFAMILY::SockFamily domain, const string& ip, DWORD port) :UdpServer(domain, ip, port), _ip(ip), _port(port) { }

	private:
		virtual bool Start()
		{
			_str.resize(1024);
			this->PostReadMsg(const_cast<char*>(_str.data()), _str.size(), &_addr);
			return true;
		}

		virtual DWORD CompleteRecvMsg(size_t size, LibTools::CSockAddr* addr, const char* msg)
		{
			if (msg) {
				LOG_TOOLS(LibTools::LOG_NORMAL) << "recv error:" << msg;
			}
			else
			{
				string ip;
				addr->GetAddr(ip);
				LOG_TOOLS(LibTools::LOG_NORMAL) << "[addr ip = " << ip << ", port = " << addr->GetPort() << "]";

				_str.erase(_str.begin() + size, _str.end());
				if (_str.find("ping ") != string::npos)
				{
					LOG_TOOLS(LibTools::LOG_NORMAL) << "[msgsize = " << size << ", msg = " << _str << "]";
					_str.replace(_str.begin(), _str.begin() + 4, "pong");
					PostSendMsg(_str.data(), _str.size(), &_addr);
				}
				else 
				{
					// echo
					LOG_TOOLS(LibTools::LOG_NORMAL) << "[recv echo:" << _str << ", " << size << "]";
					PostSendMsg(_str.c_str(), _str.size(), addr);
				}
			}

			return 0;
		}

		virtual DWORD CompleteSendMsg(size_t size, LibTools::CSockAddr* addr, const char* msg)
		{
			// error
			if (msg) {
				LOG_TOOLS(LibTools::LOG_NORMAL) << "send error:" << msg;
			}
			else {
				LOG_TOOLS(LibTools::LOG_NORMAL) << "send succ:" << size;
			}

			_str.resize(1024);
			PostReadMsg(const_cast<char*>(_str.data()), _str.size(), addr);

			return 0;
		}

	private:
		LibTools::CSockAddr _addr;
		string _str;
		string _ip;
		DWORD _port;
	};
}

#ifdef TEST_UDP_SERVER_RECV_MSG
int main(int argc, char** argv)
{
	LibTools::ShareApi::PrintDumpInfo();
	string ip;
	DWORD port = 0;
	if (argc > 2)
	{
		ip = argv[1];
		port = atoi(argv[2]);
	}
	else
	{
		ip = "0.0.0.0";
		port = 5558;
	}
	LOG_SET_WRITE_CONSOLE(true);
	udp_recv_msg::MyUdpService service(LibTools::SOCKFAMILY::IPV4, ip, port);

	service.Run();

	LOG_TOOLS(LibTools::LOG_NORMAL) << "exit...";
	return 0;
}
#endif